package qx.hyj.petrescue.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import qx.hyj.petrescue.exception.TokenErrorException;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JWTUtil {
    // 定义一个密钥
    private static final String SECURITY = "dfdhkhgjdfsfndfbgdfhdf";

    // 创建一个token
    public static String createToken(Integer id){
        // 创建一个map，用于存储token的头部信息
        Map<String,String> map = new HashMap<String,String>();
        map.put("alg","HS256"); //描述加密类型
        map.put("typ","jwt");   //描述身份验证的工具
        // 使用JWT创建一个token，并设置头部信息、签发时间、过期时间、公共信息
        return JWT.create().withHeader(Collections.unmodifiableMap(map))
                .withIssuedAt(new Date())  // 当前时间为签发时间
                //30天过期
                .withExpiresAt(Date.from(LocalDateTime.now().plusDays(30).atZone(ZoneId.systemDefault()).toInstant()))
                .withClaim("id",id) //公共信息中加入id
                .sign(Algorithm.HMAC256(SECURITY));
    }

    // 验证token
    public static Map<String, Claim> verifyToken(String token) throws TokenErrorException {
        DecodedJWT jwt = null;
        try {
            // 创建一个JWTVerifier，用于验证token
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECURITY)).build();
            // 验证token
            jwt = verifier.verify(token);
        } catch (Exception e) {
            // 如果验证失败，抛出TokenErrorException
            throw new TokenErrorException();
        }
        // 返回token中的公共信息
        return jwt.getClaims();
    }

    // 获取token中的用户id
    public static Integer getUserId(String token) throws TokenErrorException {
        // 验证token
        Map<String, Claim> claims = verifyToken(token);
        // 获取token中的id
        Claim user_id_claim = claims.get("id");
        // 如果id不存在或者id为空，抛出TokenErrorException
        if (null == user_id_claim || user_id_claim.asInt() == null) {
            throw new TokenErrorException("id is not right");
        }
        // 返回id
        return user_id_claim.asInt();
    }
}
